/*-
 * Copyright (c) 2014 Shang-Rong Cai. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $ DIDF: didview.c    Rev. 0.1.4    2014-03-26T13:37+08:00 $
 */

#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <unistd.h>
#include <complex.h>

#include <did.h>

#define STYLE_DEFAULT      0  /* Show head, meta, or body */
#define STYLE_INDEX_FIRST  1  /* Show by given first index */
#define STYLE_INDEX_SECOND 2  /* Show by given second index */
#define STYLE_USAGE        3  /* Show usage */

#define FLAG_OPTIONS_VIEWER 0  /* Set for default */
#define FLAG_OPTIONS_CUSTOM 1  /* Custom setting options */

#define FLAG_INFO_NONE 0  /* Set flag that does not show information */
#define FLAG_INFO_SHOW 1  /* Set flag to show information */

#define META_INFO_NONE   0
#define META_INFO_BRIEF  1  /* Show brief information for meta */
#define META_INFO_DETAIL 2  /* Show detail information for meta */


void usage();

int stdout_layout_default(FILE *fpif, int hflg, int mflg, int bflg, int dflg);

int stdout_layout_index_first(FILE *fpif, uint64_t target);

int stdout_layout_index_second(FILE *fpif, uint64_t target);


/* For Body of Default Layout */
int stdout_info_body_fst(FILE *fpif, did_head_t *hdprt, did_meta_t *mtprt);

int stdout_info_body_snd(FILE *fpif, did_head_t *hdprt, did_meta_t *mtprt);


/* Print Body Data */
void print_i32_f32(FILE *fpif, uint64_t sz, int32_t *dst);

void print_i32_f64(FILE *fpif, uint64_t sz, int32_t *dst);

void print_i32_c32(FILE *fpif, uint64_t sz, int32_t *dst);

void print_i32_c64(FILE *fpif, uint64_t sz, int32_t *dst);

void print_i32_i32(FILE *fpif, uint64_t sz, int32_t *dst);

void print_i32_i64(FILE *fpif, uint64_t sz, int32_t *dst);


void print_i64_f32(FILE *fpif, uint64_t sz, int64_t *dst);

void print_i64_f64(FILE *fpif, uint64_t sz, int64_t *dst);

void print_i64_c32(FILE *fpif, uint64_t sz, int64_t *dst);

void print_i64_c64(FILE *fpif, uint64_t sz, int64_t *dst);

void print_i64_i32(FILE *fpif, uint64_t sz, int64_t *dst);

void print_i64_i64(FILE *fpif, uint64_t sz, int64_t *dst);


/* Print By Given A First Index */
void print_fst_idx_i32_f32(FILE *fpif, long ide_offset);

void print_fst_idx_i32_f64(FILE *fpif, long ide_offset);

void print_fst_idx_i32_c32(FILE *fpif, long ide_offset);

void print_fst_idx_i32_c64(FILE *fpif, long ide_offset);

void print_fst_idx_i32_i32(FILE *fpif, long ide_offset);

void print_fst_idx_i32_i64(FILE *fpif, long ide_offset);


void print_fst_idx_i64_f32(FILE *fpif, long ide_offset);

void print_fst_idx_i64_f64(FILE *fpif, long ide_offset);

void print_fst_idx_i64_c32(FILE *fpif, long ide_offset);

void print_fst_idx_i64_c64(FILE *fpif, long ide_offset);

void print_fst_idx_i64_i32(FILE *fpif, long ide_offset);

void print_fst_idx_i64_i64(FILE *fpif, long ide_offset);


/* Print By Given A Second Index */
void print_snd_idx_i32_f32(FILE *fpif, long ioa_offset, long dst_offset, long ide_offset);

void print_snd_idx_i32_f64(FILE *fpif, long ioa_offset, long dst_offset, long ide_offset);

void print_snd_idx_i32_c32(FILE *fpif, long ioa_offset, long dst_offset, long ide_offset);

void print_snd_idx_i32_c64(FILE *fpif, long ioa_offset, long dst_offset, long ide_offset);

void print_snd_idx_i32_i32(FILE *fpif, long ioa_offset, long dst_offset, long ide_offset);

void print_snd_idx_i32_i64(FILE *fpif, long ioa_offset, long dst_offset, long ide_offset);


void print_snd_idx_i64_f32(FILE *fpif, long ioa_offset, long dst_offset, long ide_offset);

void print_snd_idx_i64_f64(FILE *fpif, long ioa_offset, long dst_offset, long ide_offset);

void print_snd_idx_i64_c32(FILE *fpif, long ioa_offset, long dst_offset, long ide_offset);

void print_snd_idx_i64_c64(FILE *fpif, long ioa_offset, long dst_offset, long ide_offset);

void print_snd_idx_i64_i32(FILE *fpif, long ioa_offset, long dst_offset, long ide_offset);

void print_snd_idx_i64_i64(FILE *fpif, long ioa_offset, long dst_offset, long ide_offset);


int main(int argc, char *argv[])
{
    int ierr = ERRNO_UNDEFINED;

    int cur_argc;
    char **cur_argv;

    int opti;

    FILE *fpif;

    int flg_style;  /* Layout style */

    int flg_options;  /* Flag for default options */
    int flg_head;  /* Flag for show head only (-h) */
    int flg_meta;  /* Flag for show detial meta (-m | -n)*/
    int flg_body_fst;  /* Flag for show body by first index (-b) */
    int flg_body_snd;  /* Flag for show body by second index (-d) */

    uint64_t idx_target;  /* Target index */

    /* Initialize */
    fpif = NULL;
    flg_style = STYLE_DEFAULT;
    flg_options = FLAG_OPTIONS_VIEWER;
    flg_head = FLAG_INFO_NONE;
    flg_meta = META_INFO_NONE;
    flg_body_fst = FLAG_INFO_NONE;
    flg_body_snd = FLAG_INFO_NONE;

    cur_argc = argc;
    cur_argv = argv;

    while ((opti = getopt(cur_argc, cur_argv, "bdf:hmns:")) != -1)
    {
        switch (opti)
        {
            case 'b':
                flg_style = STYLE_DEFAULT;
                flg_options = FLAG_OPTIONS_CUSTOM;
                flg_body_fst = FLAG_INFO_SHOW;
                break;
            case 'd':
                flg_style = STYLE_DEFAULT;
                flg_options = FLAG_OPTIONS_CUSTOM;
                flg_body_snd = FLAG_INFO_SHOW;
                break;
            case 'f':
                flg_style = STYLE_INDEX_FIRST;
                sscanf(optarg, "%ld", &idx_target);
                break;
            case 'h':
                flg_style = STYLE_DEFAULT;
                flg_options = FLAG_OPTIONS_CUSTOM;
                flg_head = FLAG_INFO_SHOW;
                break;
            case 'm':
                flg_style = STYLE_DEFAULT;
                flg_options = FLAG_OPTIONS_CUSTOM;
                flg_meta = META_INFO_DETAIL;
                break;
            case 'n':
                flg_style = STYLE_DEFAULT;
                flg_options = FLAG_OPTIONS_CUSTOM;
                flg_meta = META_INFO_BRIEF;
                break;
            case 's':
                flg_style = STYLE_INDEX_SECOND;
                sscanf(optarg, "%ld", &idx_target);
                break;
        }
    }

    if (flg_options == FLAG_OPTIONS_VIEWER)
    {
        flg_head = FLAG_INFO_SHOW;
        flg_meta = META_INFO_BRIEF;
        flg_body_fst = FLAG_INFO_SHOW;
    }

    cur_argc -= optind;
    cur_argv += optind;

    if (cur_argc < 1)
    {
        usage();
        goto EXIT_MAIN;
    }
    else
    {
        fpif = fopen(cur_argv[cur_argc - 1], "r");

        if (fpif == NULL)
        {
            perror(cur_argv[cur_argc - 1]);
            goto EXIT_MAIN;
        }
    }

    switch (flg_style)
    {
        case STYLE_DEFAULT:
            printf("Duplex Index Data File:\n");
            ierr = stdout_layout_default(fpif, flg_head, flg_meta, flg_body_fst, flg_body_snd);
            break;
        case STYLE_INDEX_FIRST:
            ierr = stdout_layout_index_first(fpif, idx_target);
            break;
        case STYLE_INDEX_SECOND:
            ierr = stdout_layout_index_second(fpif, idx_target);
            break;
    }

    fclose(fpif);

    EXIT_MAIN:

    return ierr;
}


void usage()
{
    printf("usage: didview [-bdhmn | -f index | -s index] file\n");
}


int stdout_layout_default(FILE *fpif, int hflg, int mflg, int bflg, int dflg)
{
    int ierr = ERRNO_UNDEFINED;

    did_head_t hdprt;
    did_meta_t mtprt;

    ierr = did_read_head(fpif, &hdprt);
    ierr = did_read_meta(fpif, &mtprt);

    if (hflg == FLAG_INFO_SHOW)
    {
        ierr = did_head_stdout(&hdprt);
    }

    switch (mflg)
    {
        case META_INFO_BRIEF:
            printf("Size Information:\n");
            printf("    Least Upper Bound of First Index: %ld\n", mtprt.fst_idx_sz);
            printf("    Least Upper Bound of Second Index: %ld\n", mtprt.snd_idx_sz);
            printf("    Number of Data Entries: %ld\n", mtprt.dat_ent_sz);
            break;
        case META_INFO_DETAIL:
            ierr = did_meta_stdout(&mtprt);
            break;
    }

    if (bflg == FLAG_INFO_SHOW)
    {
        printf("By First Index:\n");
        printf("================================================================================\n");
        stdout_info_body_fst(fpif, &hdprt, &mtprt);
    }

    if (dflg == FLAG_INFO_SHOW)
    {
        printf("By Second Index:\n");
        printf("================================================================================\n");
        stdout_info_body_snd(fpif, &hdprt, &mtprt);
    }

    return ierr;    
}


int stdout_layout_index_first(FILE *fpif, uint64_t target)
{
    int ierr = ERRNO_UNDEFINED;

    did_head_t hdprt;
    did_meta_t mtprt;

    ierr = did_read_head(fpif, &hdprt);
    ierr = did_read_meta(fpif, &mtprt);

    if (target >= mtprt.fst_idx_sz)
    {
        printf("ERROR: Index out of range\n");
    }
    else
    {
        printf("First Index: %ld\n", target);

        switch (hdprt.index_type)
        {
            case DID_HEAD_INDEX_T_I32:
                fseek(fpif, mtprt.fst_idx_dst_addr + target * sizeof(int32_t), SEEK_SET);

                switch (hdprt.entry_type)
                {
                    case DID_HEAD_DATA_T_F32:
                        print_fst_idx_i32_f32(fpif, (long) mtprt.idx_dat_lst_addr);
                        break;
                    case DID_HEAD_DATA_T_F64:
                        print_fst_idx_i32_f64(fpif, (long) mtprt.idx_dat_lst_addr);
                        break;
                    case DID_HEAD_DATA_T_C32:
                        print_fst_idx_i32_c32(fpif, (long) mtprt.idx_dat_lst_addr);
                        break;
                    case DID_HEAD_DATA_T_C64:
                        print_fst_idx_i32_c64(fpif, (long) mtprt.idx_dat_lst_addr);
                        break;
                    case DID_HEAD_DATA_T_I32:
                        print_fst_idx_i32_i32(fpif, (long) mtprt.idx_dat_lst_addr);
                        break;
                    case DID_HEAD_DATA_T_I64:
                        print_fst_idx_i32_i64(fpif, (long) mtprt.idx_dat_lst_addr);
                        break;
                }
                break;
            case DID_HEAD_INDEX_T_I64:
                fseek(fpif, mtprt.fst_idx_dst_addr + target * sizeof(int64_t), SEEK_SET);

                switch (hdprt.entry_type)
                {
                    case DID_HEAD_DATA_T_F32:
                        print_fst_idx_i64_f32(fpif, (long) mtprt.idx_dat_lst_addr);
                        break;
                    case DID_HEAD_DATA_T_F64:
                        print_fst_idx_i64_f64(fpif, (long) mtprt.idx_dat_lst_addr);
                        break;
                    case DID_HEAD_DATA_T_C32:
                        print_fst_idx_i64_c32(fpif, (long) mtprt.idx_dat_lst_addr);
                        break;
                    case DID_HEAD_DATA_T_C64:
                        print_fst_idx_i64_c64(fpif, (long) mtprt.idx_dat_lst_addr);
                        break;
                    case DID_HEAD_DATA_T_I32:
                        print_fst_idx_i64_i32(fpif, (long) mtprt.idx_dat_lst_addr);
                        break;
                    case DID_HEAD_DATA_T_I64:
                        print_fst_idx_i64_i64(fpif, (long) mtprt.idx_dat_lst_addr);
                        break;
                }
                break;
        }
    }

    return ierr;
}


int stdout_layout_index_second(FILE *fpif, uint64_t target)
{
    int ierr = ERRNO_UNDEFINED;

    did_head_t hdprt;
    did_meta_t mtprt;

    ierr = did_read_head(fpif, &hdprt);
    ierr = did_read_meta(fpif, &mtprt);

    if (target >= mtprt.snd_idx_sz)
    {
        printf("ERROR: Index out of range\n");
    }
    else
    {
        printf("Second Index: %ld\n", target);
        switch (hdprt.index_type)
        {
            case DID_HEAD_INDEX_T_I32:
                fseek(fpif, mtprt.snd_idx_dst_addr + target * sizeof(int32_t), SEEK_SET);

                switch (hdprt.entry_type)
                {
                    case DID_HEAD_DATA_T_F32:
                        print_snd_idx_i32_f32(fpif, (long) mtprt.idx_shf_lst_addr, (long) mtprt.fst_idx_dst_addr, (long) mtprt.idx_dat_lst_addr);
                        break;
                    case DID_HEAD_DATA_T_F64:
                        print_snd_idx_i32_f64(fpif, (long) mtprt.idx_shf_lst_addr, (long) mtprt.fst_idx_dst_addr, (long) mtprt.idx_dat_lst_addr);
                        break;
                    case DID_HEAD_DATA_T_C32:
                        print_snd_idx_i32_c32(fpif, (long) mtprt.idx_shf_lst_addr, (long) mtprt.fst_idx_dst_addr, (long) mtprt.idx_dat_lst_addr);
                        break;
                    case DID_HEAD_DATA_T_C64:
                        print_snd_idx_i32_c64(fpif, (long) mtprt.idx_shf_lst_addr, (long) mtprt.fst_idx_dst_addr, (long) mtprt.idx_dat_lst_addr);
                        break;
                    case DID_HEAD_DATA_T_I32:
                        print_snd_idx_i32_i32(fpif, (long) mtprt.idx_shf_lst_addr, (long) mtprt.fst_idx_dst_addr, (long) mtprt.idx_dat_lst_addr);
                        break;
                    case DID_HEAD_DATA_T_I64:
                        print_snd_idx_i32_i64(fpif, (long) mtprt.idx_shf_lst_addr, (long) mtprt.fst_idx_dst_addr, (long) mtprt.idx_dat_lst_addr);
                        break;
                }
                break;
            case DID_HEAD_INDEX_T_I64:
                fseek(fpif, mtprt.snd_idx_dst_addr + target * sizeof(int64_t), SEEK_SET);

                switch (hdprt.entry_type)
                {
                    case DID_HEAD_DATA_T_F32:
                        print_snd_idx_i64_f32(fpif, (long) mtprt.idx_shf_lst_addr, (long) mtprt.fst_idx_dst_addr, (long) mtprt.idx_dat_lst_addr);
                        break;
                    case DID_HEAD_DATA_T_F64:
                        print_snd_idx_i64_f64(fpif, (long) mtprt.idx_shf_lst_addr, (long) mtprt.fst_idx_dst_addr, (long) mtprt.idx_dat_lst_addr);
                        break;
                    case DID_HEAD_DATA_T_C32:
                        print_snd_idx_i64_c32(fpif, (long) mtprt.idx_shf_lst_addr, (long) mtprt.fst_idx_dst_addr, (long) mtprt.idx_dat_lst_addr);
                        break;
                    case DID_HEAD_DATA_T_C64:
                        print_snd_idx_i64_c64(fpif, (long) mtprt.idx_shf_lst_addr, (long) mtprt.fst_idx_dst_addr, (long) mtprt.idx_dat_lst_addr);
                        break;
                    case DID_HEAD_DATA_T_I32:
                        print_snd_idx_i64_i32(fpif, (long) mtprt.idx_shf_lst_addr, (long) mtprt.fst_idx_dst_addr, (long) mtprt.idx_dat_lst_addr);
                        break;
                    case DID_HEAD_DATA_T_I64:
                        print_snd_idx_i64_i64(fpif, (long) mtprt.idx_shf_lst_addr, (long) mtprt.fst_idx_dst_addr, (long) mtprt.idx_dat_lst_addr);
                        break;
                }
                break;
        }
    }

    return ierr;
}


int stdout_info_body_fst(FILE *fpif, did_head_t *hdprt, did_meta_t *mtprt)
{
    int ierr = ERRNO_UNDEFINED;

    void *idx_dst;

    size_t idx_sz;

    /* Initialize */
    idx_dst = NULL;
    idx_sz = 0;

    switch (hdprt->index_type)
    {
        case DID_HEAD_INDEX_T_I32:
            idx_sz = sizeof(int32_t);
            break;
        case DID_HEAD_INDEX_T_I64:
            idx_sz = sizeof(int64_t);
            break;
    }

    idx_dst = calloc((size_t) mtprt->fst_idx_sz + 1, idx_sz);

    /* Distribution Depended On First Index */
    fseek(fpif, mtprt->fst_idx_dst_addr, SEEK_SET);
    fread(idx_dst, idx_sz, (size_t) mtprt->fst_idx_sz + 1, fpif);

    fseek(fpif, mtprt->idx_dat_lst_addr, SEEK_SET);

    switch (hdprt->index_type)
    {
        case DID_HEAD_INDEX_T_I32:
            switch (hdprt->entry_type)
            {
                case DID_HEAD_DATA_T_F32:
                    print_i32_f32(fpif, mtprt->fst_idx_sz, (int32_t*) idx_dst);
                    break;
                case DID_HEAD_DATA_T_F64:
                    print_i32_f64(fpif, mtprt->fst_idx_sz, (int32_t*) idx_dst);
                    break;
                case DID_HEAD_DATA_T_C32:
                    print_i32_c32(fpif, mtprt->fst_idx_sz, (int32_t*) idx_dst);
                    break;
                case DID_HEAD_DATA_T_C64:
                    print_i32_c64(fpif, mtprt->fst_idx_sz, (int32_t*) idx_dst);
                    break;
                case DID_HEAD_DATA_T_I32:
                    print_i32_i32(fpif, mtprt->fst_idx_sz, (int32_t*) idx_dst);
                    break;
                case DID_HEAD_DATA_T_I64:
                    print_i32_i64(fpif, mtprt->fst_idx_sz, (int32_t*) idx_dst);
                    break;
            }
            break;
        case DID_HEAD_INDEX_T_I64:
            switch (hdprt->entry_type)
            {
                case DID_HEAD_DATA_T_F32:
                    print_i64_f32(fpif, mtprt->fst_idx_sz, (int64_t*) idx_dst);
                    break;
                case DID_HEAD_DATA_T_F64:
                    print_i64_f64(fpif, mtprt->fst_idx_sz, (int64_t*) idx_dst);
                    break;
                case DID_HEAD_DATA_T_C32:
                    print_i64_c32(fpif, mtprt->fst_idx_sz, (int64_t*) idx_dst);
                    break;
                case DID_HEAD_DATA_T_C64:
                    print_i64_c64(fpif, mtprt->fst_idx_sz, (int64_t*) idx_dst);
                    break;
                case DID_HEAD_DATA_T_I32:
                    print_i64_i32(fpif, mtprt->fst_idx_sz, (int64_t*) idx_dst);
                    break;
                case DID_HEAD_DATA_T_I64:
                    print_i64_i64(fpif, mtprt->fst_idx_sz, (int64_t*) idx_dst);
                    break;
            }
            break;
    }


    free(idx_dst);

    return ierr;
}


int stdout_info_body_snd(FILE *fpif, did_head_t *hdprt, did_meta_t *mtprt)
{
    int ierr = ERRNO_UNDEFINED;

    void *idx_dst;

    size_t idx_sz;

    /* Initialize */
    idx_dst = NULL;
    idx_sz = 0;

    switch (hdprt->index_type)
    {
        case DID_HEAD_INDEX_T_I32:
            idx_sz = sizeof(int32_t);
            break;
        case DID_HEAD_INDEX_T_I64:
            idx_sz = sizeof(int64_t);
            break;
    }

    idx_dst = calloc((size_t) mtprt->snd_idx_sz + 1, idx_sz);

    /* Distribution Depended On Second Index */
    fseek(fpif, mtprt->snd_idx_dst_addr, SEEK_SET);
    fread(idx_dst, idx_sz, (size_t) mtprt->snd_idx_sz + 1, fpif);

    fseek(fpif, mtprt->idx_shf_lst_addr, SEEK_SET);

    switch (hdprt->index_type)
    {
        case DID_HEAD_INDEX_T_I32:
            print_i32_i32(fpif, mtprt->snd_idx_sz, idx_dst);
            break;
        case DID_HEAD_INDEX_T_I64:
            print_i64_i64(fpif, mtprt->snd_idx_sz, idx_dst);
            break;
    }

    return ierr;
}


/* Print Body Data */
void print_i32_f32(FILE *fpif, uint64_t sz, int32_t *dst)
{
    uint64_t ui, uj;

    int32_t buf_i32;
    float buf_f32;

    for (ui = 0; ui < sz; ui++)
    {
        for (uj = dst[ui]; uj < dst[ui + 1]; uj++)
        {
            fread((void*) &buf_i32, sizeof(int32_t), 1, fpif);
            fread((void*) &buf_f32, sizeof(float), 1, fpif);
            printf("%7ld: (%7ld, %7d)  % .7E\n", uj, ui, buf_i32, buf_f32);
        }
    }
}


void print_i32_f64(FILE *fpif, uint64_t sz, int32_t *dst)
{
    uint64_t ui, uj;

    int32_t buf_i32;
    double buf_f64;

    for (ui = 0; ui < sz; ui++)
    {
        for (uj = dst[ui]; uj < dst[ui + 1]; uj++)
        {
            fread((void*) &buf_i32, sizeof(int32_t), 1, fpif);
            fread((void*) &buf_f64, sizeof(double), 1, fpif);
            printf("%7ld: (%7ld, %7d)  % .15lE\n", uj, ui, buf_i32, buf_f64);
        }
    }
}


void print_i32_c32(FILE *fpif, uint64_t sz, int32_t *dst)
{
    uint64_t ui, uj;

    int32_t buf_i32;
    float complex buf_c32;

    for (ui = 0; ui < sz; ui++)
    {
        for (uj = dst[ui]; uj < dst[ui + 1]; uj++)
        {
            fread((void*) &buf_i32, sizeof(int32_t), 1, fpif);
            fread((void*) &buf_c32, sizeof(float complex), 1, fpif);
            printf("%7ld: (%7ld, %7d)  % .7E + % .7E * i\n", uj, ui, buf_i32, crealf(buf_c32), cimagf(buf_c32));
        }
    }
}


void print_i32_c64(FILE *fpif, uint64_t sz, int32_t *dst)
{
    uint64_t ui, uj;

    int32_t buf_i32;
    double complex buf_c64;

    for (ui = 0; ui < sz; ui++)
    {
        for (uj = dst[ui]; uj < dst[ui + 1]; uj++)
        {
            fread((void*) &buf_i32, sizeof(int32_t), 1, fpif);
            fread((void*) &buf_c64, sizeof(double complex), 1, fpif);
            printf("%7ld: (%7ld, %7d)  % .15lE + % .15lE * i\n", uj, ui, buf_i32, creal(buf_c64), cimag(buf_c64));
        }
    }
}


void print_i32_i32(FILE *fpif, uint64_t sz, int32_t *dst)
{
    uint64_t ui, uj;

    int32_t buf_idx;
    int32_t buf_val;

    for (ui = 0; ui < sz; ui++)
    {
        for (uj = dst[ui]; uj < dst[ui + 1]; uj++)
        {
            fread((void*) &buf_idx, sizeof(int32_t), 1, fpif);
            fread((void*) &buf_val, sizeof(int32_t), 1, fpif);
            printf("%7ld: (%7ld, %7d)  % 7d\n", uj, ui, buf_idx, buf_val);
        }
    }
}


void print_i32_i64(FILE *fpif, uint64_t sz, int32_t *dst)
{
    uint64_t ui, uj;

    int32_t buf_idx;
    int64_t buf_val;

    for (ui = 0; ui < sz; ui++)
    {
        for (uj = dst[ui]; uj < dst[ui + 1]; uj++)
        {
            fread((void*) &buf_idx, sizeof(int32_t), 1, fpif);
            fread((void*) &buf_val, sizeof(int64_t), 1, fpif);
            printf("%7ld: (%7ld, %7d)  % 7ld\n", uj, ui, buf_idx, buf_val);
        }
    }
}


void print_i64_f32(FILE *fpif, uint64_t sz, int64_t *dst)
{
    uint64_t ui, uj;

    int64_t buf_i64;
    float buf_f32;

    for (ui = 0; ui < sz; ui++)
    {
        for (uj = dst[ui]; uj < dst[ui + 1]; uj++)
        {
            fread((void*) &buf_i64, sizeof(int64_t), 1, fpif);
            fread((void*) &buf_f32, sizeof(float), 1, fpif);
            printf("%7ld: (%7ld, %7ld)  % .7E\n", uj, ui, buf_i64, buf_f32);
        }
    }
}


void print_i64_f64(FILE *fpif, uint64_t sz, int64_t *dst)
{
    uint64_t ui, uj;

    int64_t buf_i64;
    double buf_f64;

    for (ui = 0; ui < sz; ui++)
    {
        for (uj = dst[ui]; uj < dst[ui + 1]; uj++)
        {
            fread((void*) &buf_i64, sizeof(int64_t), 1, fpif);
            fread((void*) &buf_f64, sizeof(double), 1, fpif);
            printf("%7ld: (%7ld, %7ld)  % .15lE\n", uj, ui, buf_i64, buf_f64);
        }
    }
}


void print_i64_c32(FILE *fpif, uint64_t sz, int64_t *dst)
{
    uint64_t ui, uj;

    int64_t buf_i64;
    float complex buf_c32;

    for (ui = 0; ui < sz; ui++)
    {
        for (uj = dst[ui]; uj < dst[ui + 1]; uj++)
        {
            fread((void*) &buf_i64, sizeof(int64_t), 1, fpif);
            fread((void*) &buf_c32, sizeof(float complex), 1, fpif);
            printf("%7ld: (%7ld, %7ld)  % .7E + % .7E * i\n", uj, ui, buf_i64, crealf(buf_c32), cimagf(buf_c32));
        }
    }
}


void print_i64_c64(FILE *fpif, uint64_t sz, int64_t *dst)
{
    uint64_t ui, uj;

    int64_t buf_i64;
    double complex buf_c64;

    for (ui = 0; ui < sz; ui++)
    {
        for (uj = dst[ui]; uj < dst[ui + 1]; uj++)
        {
            fread((void*) &buf_i64, sizeof(int64_t), 1, fpif);
            fread((void*) &buf_c64, sizeof(double complex), 1, fpif);
            printf("%7ld: (%7ld, %7ld)  % .15lE + % .15lE * i\n", uj, ui, buf_i64, creal(buf_c64), cimag(buf_c64));
        }
    }
}


void print_i64_i32(FILE *fpif, uint64_t sz, int64_t *dst)
{
    uint64_t ui, uj;

    int64_t buf_idx;
    int32_t buf_val;

    for (ui = 0; ui < sz; ui++)
    {
        for (uj = dst[ui]; uj < dst[ui + 1]; uj++)
        {
            fread((void*) &buf_idx, sizeof(int64_t), 1, fpif);
            fread((void*) &buf_val, sizeof(int32_t), 1, fpif);
            printf("%7ld: (%7ld, %7ld)  % 7d\n", uj, ui, buf_idx, buf_val);
        }
    }
}


void print_i64_i64(FILE *fpif, uint64_t sz, int64_t *dst)
{
    uint64_t ui, uj;

    int64_t buf_idx;
    int64_t buf_val;

    for (ui = 0; ui < sz; ui++)
    {
        for (uj = dst[ui]; uj < dst[ui + 1]; uj++)
        {
            fread((void*) &buf_idx, sizeof(int64_t), 1, fpif);
            fread((void*) &buf_val, sizeof(int64_t), 1, fpif);
            printf("%7ld: (%7ld, %7ld)  % 7ld\n", uj, ui, buf_idx, buf_val);
        }
    }
}


/* Print By Given A First Index */
void print_fst_idx_i32_f32(FILE *fpif, long ide_offset)
{
    int32_t ii;
    int32_t head_i32, tail_i32;

    int32_t buf_i32;
    float buf_f32;

    fread((void*) &head_i32, sizeof(int32_t), 1, fpif);
    fread((void*) &tail_i32, sizeof(int32_t), 1, fpif);

    fseek(fpif, ide_offset + head_i32 * (sizeof(int32_t) + sizeof(float)), SEEK_SET);

    for (ii = 0; ii < tail_i32 - head_i32; ii++)
    {
        fread((void*) &buf_i32, sizeof(int32_t), 1, fpif);
        fread((void*) &buf_f32, sizeof(float), 1, fpif);
        printf("%7d: % .7E\n", buf_i32, buf_f32);
    }
}


void print_fst_idx_i32_f64(FILE *fpif, long ide_offset)
{
    int32_t ii;
    int32_t head_i32, tail_i32;

    int32_t buf_i32;
    double buf_f64;

    fread((void*) &head_i32, sizeof(int32_t), 1, fpif);
    fread((void*) &tail_i32, sizeof(int32_t), 1, fpif);

    fseek(fpif, ide_offset + head_i32 * (sizeof(int32_t) + sizeof(double)), SEEK_SET);

    for (ii = 0; ii < tail_i32 - head_i32; ii++)
    {
        fread((void*) &buf_i32, sizeof(int32_t), 1, fpif);
        fread((void*) &buf_f64, sizeof(double), 1, fpif);
        printf("%7d: % .15lE\n", buf_i32, buf_f64);
    }
}


void print_fst_idx_i32_c32(FILE *fpif, long ide_offset)
{
    int32_t ii;
    int32_t head_i32, tail_i32;

    int32_t buf_i32;
    float complex buf_c32;

    fread((void*) &head_i32, sizeof(int32_t), 1, fpif);
    fread((void*) &tail_i32, sizeof(int32_t), 1, fpif);

    fseek(fpif, ide_offset + head_i32 * (sizeof(int32_t) + sizeof(float complex)), SEEK_SET);

    for (ii = 0; ii < tail_i32 - head_i32; ii++)
    {
        fread((void*) &buf_i32, sizeof(int32_t), 1, fpif);
        fread((void*) &buf_c32, sizeof(float), 1, fpif);
        printf("%7d: % .7E + % .7E * i\n", buf_i32, crealf(buf_c32), cimagf(buf_c32));
    }
}


void print_fst_idx_i32_c64(FILE *fpif, long ide_offset)
{
    int32_t ii;
    int32_t head_i32, tail_i32;

    int32_t buf_i32;
    double complex buf_c64;

    fread((void*) &head_i32, sizeof(int32_t), 1, fpif);
    fread((void*) &tail_i32, sizeof(int32_t), 1, fpif);

    fseek(fpif, ide_offset + head_i32 * (sizeof(int32_t) + sizeof(double complex)), SEEK_SET);

    for (ii = 0; ii < tail_i32 - head_i32; ii++)
    {
        fread((void*) &buf_i32, sizeof(int32_t), 1, fpif);
        fread((void*) &buf_c64, sizeof(double complex), 1, fpif);
        printf("%7d: % .15lE + % 15lE * i\n", buf_i32, creal(buf_c64), cimag(buf_c64));
    }
}


void print_fst_idx_i32_i32(FILE *fpif, long ide_offset)
{
    int32_t ii;
    int32_t head_i32, tail_i32;

    int32_t buf_i32;

    fread((void*) &head_i32, sizeof(int32_t), 1, fpif);
    fread((void*) &tail_i32, sizeof(int32_t), 1, fpif);

    fseek(fpif, ide_offset + head_i32 * sizeof(int32_t) * 2, SEEK_SET);

    for (ii = 0; ii < tail_i32 - head_i32; ii++)
    {
        fread((void*) &buf_i32, sizeof(int32_t), 1, fpif);
        printf("%7d: ", buf_i32);
        fread((void*) &buf_i32, sizeof(int32_t), 1, fpif);
        printf("% 7d\n", buf_i32);

    }
}


void print_fst_idx_i32_i64(FILE *fpif, long ide_offset)
{
    int32_t ii;
    int32_t head_i32, tail_i32;

    int32_t buf_i32;
    int64_t buf_i64;

    fread((void*) &head_i32, sizeof(int32_t), 1, fpif);
    fread((void*) &tail_i32, sizeof(int32_t), 1, fpif);

    fseek(fpif, ide_offset + head_i32 * (sizeof(int32_t) + sizeof(int64_t)), SEEK_SET);

    for (ii = 0; ii < tail_i32 - head_i32; ii++)
    {
        fread((void*) &buf_i32, sizeof(int32_t), 1, fpif);
        fread((void*) &buf_i64, sizeof(int64_t), 1, fpif);
        printf("%7d: % 15ld\n", buf_i32, buf_i64);
    }
}


void print_fst_idx_i64_f32(FILE *fpif, long ide_offset)
{
    int64_t ii;
    int64_t head_i64, tail_i64;

    int64_t buf_i64;
    float buf_f32;

    fread((void*) &head_i64, sizeof(int64_t), 1, fpif);
    fread((void*) &tail_i64, sizeof(int64_t), 1, fpif);

    fseek(fpif, ide_offset + head_i64 * (sizeof(int64_t) + sizeof(float)), SEEK_SET);

    for (ii = 0; ii < tail_i64 - head_i64; ii++)
    {
        fread((void*) &buf_i64, sizeof(int64_t), 1, fpif);
        fread((void*) &buf_f32, sizeof(float), 1, fpif);
        printf("%7ld: % .7E\n", buf_i64, buf_f32);
    }
}


void print_fst_idx_i64_f64(FILE *fpif, long ide_offset)
{
    int64_t ii;
    int64_t head_i64, tail_i64;

    int64_t buf_i64;
    double buf_f64;

    fread((void*) &head_i64, sizeof(int64_t), 1, fpif);
    fread((void*) &tail_i64, sizeof(int64_t), 1, fpif);

    fseek(fpif, ide_offset + head_i64 * (sizeof(int64_t) + sizeof(double)), SEEK_SET);

    for (ii = 0; ii < tail_i64 - head_i64; ii++)
    {
        fread((void*) &buf_i64, sizeof(int64_t), 1, fpif);
        fread((void*) &buf_f64, sizeof(double), 1, fpif);
        printf("%7ld: % .15lE\n", buf_i64, buf_f64);
    }
}


void print_fst_idx_i64_c32(FILE *fpif, long ide_offset)
{
    int64_t ii;
    int64_t head_i64, tail_i64;

    int64_t buf_i64;
    float complex buf_c32;

    fread((void*) &head_i64, sizeof(int64_t), 1, fpif);
    fread((void*) &tail_i64, sizeof(int64_t), 1, fpif);

    fseek(fpif, ide_offset + head_i64 * (sizeof(int64_t) + sizeof(float complex)), SEEK_SET);

    for (ii = 0; ii < tail_i64 - head_i64; ii++)
    {
        fread((void*) &buf_i64, sizeof(int64_t), 1, fpif);
        fread((void*) &buf_c32, sizeof(float), 1, fpif);
        printf("%7ld: % .7E + % .7E * i\n", buf_i64, crealf(buf_c32), cimagf(buf_c32));
    }
}


void print_fst_idx_i64_c64(FILE *fpif, long ide_offset)
{
    int64_t ii;
    int64_t head_i64, tail_i64;

    int64_t buf_i64;
    double complex buf_c64;

    fread((void*) &head_i64, sizeof(int64_t), 1, fpif);
    fread((void*) &tail_i64, sizeof(int64_t), 1, fpif);

    fseek(fpif, ide_offset + head_i64 * (sizeof(int64_t) + sizeof(double complex)), SEEK_SET);

    for (ii = 0; ii < tail_i64 - head_i64; ii++)
    {
        fread((void*) &buf_i64, sizeof(int64_t), 1, fpif);
        fread((void*) &buf_c64, sizeof(double complex), 1, fpif);
        printf("%7ld: % .15lE + % 15lE * i\n", buf_i64, creal(buf_c64), cimag(buf_c64));
    }
}


void print_fst_idx_i64_i32(FILE *fpif, long ide_offset)
{
    int64_t ii;
    int64_t head_i64, tail_i64;

    int64_t buf_i64;
    int32_t buf_i32;

    fread((void*) &head_i64, sizeof(int64_t), 1, fpif);
    fread((void*) &tail_i64, sizeof(int64_t), 1, fpif);

    fseek(fpif, ide_offset + head_i64 * (sizeof(int64_t) + sizeof(int32_t)), SEEK_SET);

    for (ii = 0; ii < tail_i64 - head_i64; ii++)
    {
        fread((void*) &buf_i64, sizeof(int64_t), 1, fpif);
        fread((void*) &buf_i32, sizeof(int32_t), 1, fpif);
        printf("%7ld: % 7d\n", buf_i64, buf_i32);

    }
}


void print_fst_idx_i64_i64(FILE *fpif, long ide_offset)
{
    int64_t ii;
    int64_t head_i64, tail_i64;

    int64_t buf_i64;

    fread((void*) &head_i64, sizeof(int64_t), 1, fpif);
    fread((void*) &tail_i64, sizeof(int64_t), 1, fpif);

    fseek(fpif, ide_offset + head_i64 * sizeof(int64_t) * 2, SEEK_SET);

    for (ii = 0; ii < tail_i64 - head_i64; ii++)
    {
        fread((void*) &buf_i64, sizeof(int64_t), 1, fpif);
        printf("%7ld: ", buf_i64);
        fread((void*) &buf_i64, sizeof(int64_t), 1, fpif);
        printf("% 15ld\n", buf_i64);
    }
}


/* Print By Given A Second Index */
void print_snd_idx_i32_f32(FILE *fpif, long ioa_offset, long dst_offset, long ide_offset)
{
    int32_t ii;
    int32_t head_i32, tail_i32;

    size_t iao_sz;
    int32_t *buf_lst;
    int32_t buf_pos;
    float buf_f32;

    fread((void*) &head_i32, sizeof(int32_t), 1, fpif);
    fread((void*) &tail_i32, sizeof(int32_t), 1, fpif);

    iao_sz = (size_t) (tail_i32 - head_i32);
    buf_lst = (int32_t*) calloc(iao_sz * 2, sizeof(int32_t));

    fseek(fpif, ioa_offset + head_i32 * (sizeof(int32_t) + sizeof(int32_t)), SEEK_SET);
    fread((void*) buf_lst, sizeof(int32_t), iao_sz * 2, fpif);

    for (ii = 0; ii < tail_i32 - head_i32; ii++)
    {
        fseek(fpif, dst_offset + sizeof(int32_t) * buf_lst[ii * 2], SEEK_SET);
        fread((void*) &buf_pos, sizeof(int32_t), 1, fpif);

        buf_pos += buf_lst[ii * 2 + 1];

        fseek(fpif, ide_offset + (sizeof(int32_t) + sizeof(float)) * buf_pos + sizeof(int32_t), SEEK_SET);
        fread((void*) &buf_f32, sizeof(float), 1, fpif);

        printf("%7d: % .7E\n", buf_lst[ii * 2], buf_f32);
    }

    free(buf_lst);
}


void print_snd_idx_i32_f64(FILE *fpif, long ioa_offset, long dst_offset, long ide_offset)
{
    int32_t ii;
    int32_t head_i32, tail_i32;

    size_t iao_sz;
    int32_t *buf_lst;
    int32_t buf_pos;
    double buf_f64;

    fread((void*) &head_i32, sizeof(int32_t), 1, fpif);
    fread((void*) &tail_i32, sizeof(int32_t), 1, fpif);

    iao_sz = (size_t) (tail_i32 - head_i32);
    buf_lst = (int32_t*) calloc(iao_sz * 2, sizeof(int32_t));

    fseek(fpif, ioa_offset + head_i32 * (sizeof(int32_t) + sizeof(int32_t)), SEEK_SET);
    fread((void*) buf_lst, sizeof(int32_t), iao_sz * 2, fpif);

    for (ii = 0; ii < tail_i32 - head_i32; ii++)
    {
        fseek(fpif, dst_offset + sizeof(int32_t) * buf_lst[ii * 2], SEEK_SET);
        fread((void*) &buf_pos, sizeof(int32_t), 1, fpif);

        buf_pos += buf_lst[ii * 2 + 1];

        fseek(fpif, ide_offset + (sizeof(int32_t) + sizeof(double)) * buf_pos + sizeof(int32_t), SEEK_SET);
        fread((void*) &buf_f64, sizeof(double), 1, fpif);

        printf("%7d: % .15lE\n", buf_lst[ii * 2], buf_f64);
    }

    free(buf_lst);
}


void print_snd_idx_i32_c32(FILE *fpif, long ioa_offset, long dst_offset, long ide_offset)
{
    int32_t ii;
    int32_t head_i32, tail_i32;

    size_t iao_sz;
    int32_t *buf_lst;
    int32_t buf_pos;
    float complex buf_c32;

    fread((void*) &head_i32, sizeof(int32_t), 1, fpif);
    fread((void*) &tail_i32, sizeof(int32_t), 1, fpif);

    iao_sz = (size_t) (tail_i32 - head_i32);
    buf_lst = (int32_t*) calloc(iao_sz * 2, sizeof(int32_t));

    fseek(fpif, ioa_offset + head_i32 * (sizeof(int32_t) + sizeof(int32_t)), SEEK_SET);
    fread((void*) buf_lst, sizeof(int32_t), iao_sz * 2, fpif);

    for (ii = 0; ii < tail_i32 - head_i32; ii++)
    {
        fseek(fpif, dst_offset + sizeof(int32_t) * buf_lst[ii * 2], SEEK_SET);
        fread((void*) &buf_pos, sizeof(int32_t), 1, fpif);

        buf_pos += buf_lst[ii * 2 + 1];

        fseek(fpif, ide_offset + (sizeof(int32_t) + sizeof(float complex)) * buf_pos + sizeof(int32_t), SEEK_SET);
        fread((void*) &buf_c32, sizeof(float complex), 1, fpif);

        printf("%7d: % .7E + % .7E * i\n", buf_lst[ii * 2], crealf(buf_c32), cimagf(buf_c32));
    }

    free(buf_lst);
}


void print_snd_idx_i32_c64(FILE *fpif, long ioa_offset, long dst_offset, long ide_offset)
{
    int32_t ii;
    int32_t head_i32, tail_i32;

    size_t iao_sz;
    int32_t *buf_lst;
    int32_t buf_pos;
    double complex buf_c64;

    fread((void*) &head_i32, sizeof(int32_t), 1, fpif);
    fread((void*) &tail_i32, sizeof(int32_t), 1, fpif);

    iao_sz = (size_t) (tail_i32 - head_i32);
    buf_lst = (int32_t*) calloc(iao_sz * 2, sizeof(int32_t));

    fseek(fpif, ioa_offset + head_i32 * (sizeof(int32_t) + sizeof(int32_t)), SEEK_SET);
    fread((void*) buf_lst, sizeof(int32_t), iao_sz * 2, fpif);

    for (ii = 0; ii < tail_i32 - head_i32; ii++)
    {
        fseek(fpif, dst_offset + sizeof(int32_t) * buf_lst[ii * 2], SEEK_SET);
        fread((void*) &buf_pos, sizeof(int32_t), 1, fpif);

        buf_pos += buf_lst[ii * 2 + 1];

        fseek(fpif, ide_offset + (sizeof(int32_t) + sizeof(double complex)) * buf_pos + sizeof(int32_t), SEEK_SET);
        fread((void*) &buf_c64, sizeof(double complex), 1, fpif);

        printf("%7d: % .15lE + % .15lE * i\n", buf_lst[ii * 2], creal(buf_c64), cimag(buf_c64));
    }

    free(buf_lst);
}


void print_snd_idx_i32_i32(FILE *fpif, long ioa_offset, long dst_offset, long ide_offset)
{
    int32_t ii;
    int32_t head_i32, tail_i32;

    size_t iao_sz;
    int32_t *buf_lst;
    int32_t buf_pos;
    int32_t buf_i32;

    fread((void*) &head_i32, sizeof(int32_t), 1, fpif);
    fread((void*) &tail_i32, sizeof(int32_t), 1, fpif);

    iao_sz = (size_t) (tail_i32 - head_i32);
    buf_lst = (int32_t*) calloc(iao_sz * 2, sizeof(int32_t));

    fseek(fpif, ioa_offset + head_i32 * (sizeof(int32_t) + sizeof(int32_t)), SEEK_SET);
    fread((void*) buf_lst, sizeof(int32_t), iao_sz * 2, fpif);

    for (ii = 0; ii < tail_i32 - head_i32; ii++)
    {
        fseek(fpif, dst_offset + sizeof(int32_t) * buf_lst[ii * 2], SEEK_SET);
        fread((void*) &buf_pos, sizeof(int32_t), 1, fpif);

        buf_pos += buf_lst[ii * 2 + 1];

        fseek(fpif, ide_offset + (sizeof(int32_t) + sizeof(int32_t)) * buf_pos + sizeof(int32_t), SEEK_SET);
        fread((void*) &buf_i32, sizeof(int32_t), 1, fpif);

        printf("%7d: % 7d\n", buf_lst[ii * 2], buf_i32);
    }

    free(buf_lst);
}


void print_snd_idx_i32_i64(FILE *fpif, long ioa_offset, long dst_offset, long ide_offset)
{
    int32_t ii;
    int32_t head_i32, tail_i32;

    size_t iao_sz;
    int32_t *buf_lst;
    int32_t buf_pos;
    int64_t buf_i64;

    fread((void*) &head_i32, sizeof(int32_t), 1, fpif);
    fread((void*) &tail_i32, sizeof(int32_t), 1, fpif);

    iao_sz = (size_t) (tail_i32 - head_i32);
    buf_lst = (int32_t*) calloc(iao_sz * 2, sizeof(int32_t));

    fseek(fpif, ioa_offset + head_i32 * (sizeof(int32_t) + sizeof(int32_t)), SEEK_SET);
    fread((void*) buf_lst, sizeof(int32_t), iao_sz * 2, fpif);

    for (ii = 0; ii < tail_i32 - head_i32; ii++)
    {
        fseek(fpif, dst_offset + sizeof(int32_t) * buf_lst[ii * 2], SEEK_SET);
        fread((void*) &buf_pos, sizeof(int32_t), 1, fpif);

        buf_pos += buf_lst[ii * 2 + 1];

        fseek(fpif, ide_offset + (sizeof(int32_t) + sizeof(int64_t)) * buf_pos + sizeof(int32_t), SEEK_SET);
        fread((void*) &buf_i64, sizeof(int64_t), 1, fpif);

        printf("%7d: % 15ld\n", buf_lst[ii * 2], buf_i64);
    }

    free(buf_lst);
}


void print_snd_idx_i64_f32(FILE *fpif, long ioa_offset, long dst_offset, long ide_offset)
{
    int64_t ii;
    int64_t head_i64, tail_i64;

    size_t iao_sz;
    int64_t *buf_lst;
    int64_t buf_pos;
    float buf_f32;

    fread((void*) &head_i64, sizeof(int64_t), 1, fpif);
    fread((void*) &tail_i64, sizeof(int32_t), 1, fpif);

    iao_sz = (size_t) (tail_i64 - head_i64);
    buf_lst = (int64_t*) calloc(iao_sz * 2, sizeof(int64_t));

    fseek(fpif, ioa_offset + head_i64 * (sizeof(int64_t) + sizeof(int64_t)), SEEK_SET);
    fread((void*) buf_lst, sizeof(int64_t), iao_sz * 2, fpif);

    for (ii = 0; ii < tail_i64 - head_i64; ii++)
    {
        fseek(fpif, dst_offset + sizeof(int64_t) * buf_lst[ii * 2], SEEK_SET);
        fread((void*) &buf_pos, sizeof(int64_t), 1, fpif);

        buf_pos += buf_lst[ii * 2 + 1];

        fseek(fpif, ide_offset + (sizeof(int64_t) + sizeof(float)) * buf_pos + sizeof(int64_t), SEEK_SET);
        fread((void*) &buf_f32, sizeof(float), 1, fpif);

        printf("%15ld: % .7E\n", buf_lst[ii * 2], buf_f32);
    }

    free(buf_lst);
}


void print_snd_idx_i64_f64(FILE *fpif, long ioa_offset, long dst_offset, long ide_offset)
{
    int64_t ii;
    int64_t head_i64, tail_i64;

    size_t iao_sz;
    int64_t *buf_lst;
    int64_t buf_pos;
    double buf_f64;

    fread((void*) &head_i64, sizeof(int64_t), 1, fpif);
    fread((void*) &tail_i64, sizeof(int32_t), 1, fpif);

    iao_sz = (size_t) (tail_i64 - head_i64);
    buf_lst = (int64_t*) calloc(iao_sz * 2, sizeof(int64_t));

    fseek(fpif, ioa_offset + head_i64 * (sizeof(int64_t) + sizeof(int64_t)), SEEK_SET);
    fread((void*) buf_lst, sizeof(int64_t), iao_sz * 2, fpif);

    for (ii = 0; ii < tail_i64 - head_i64; ii++)
    {
        fseek(fpif, dst_offset + sizeof(int64_t) * buf_lst[ii * 2], SEEK_SET);
        fread((void*) &buf_pos, sizeof(int64_t), 1, fpif);

        buf_pos += buf_lst[ii * 2 + 1];

        fseek(fpif, ide_offset + (sizeof(int64_t) + sizeof(double)) * buf_pos + sizeof(int64_t), SEEK_SET);
        fread((void*) &buf_f64, sizeof(double), 1, fpif);

        printf("%15ld: % .15lE\n", buf_lst[ii * 2], buf_f64);
    }

    free(buf_lst);
}


void print_snd_idx_i64_c32(FILE *fpif, long ioa_offset, long dst_offset, long ide_offset)
{
    int64_t ii;
    int64_t head_i64, tail_i64;

    size_t iao_sz;
    int64_t *buf_lst;
    int64_t buf_pos;
    float complex buf_c32;

    fread((void*) &head_i64, sizeof(int64_t), 1, fpif);
    fread((void*) &tail_i64, sizeof(int32_t), 1, fpif);

    iao_sz = (size_t) (tail_i64 - head_i64);
    buf_lst = (int64_t*) calloc(iao_sz * 2, sizeof(int64_t));

    fseek(fpif, ioa_offset + head_i64 * (sizeof(int64_t) + sizeof(int64_t)), SEEK_SET);
    fread((void*) buf_lst, sizeof(int64_t), iao_sz * 2, fpif);

    for (ii = 0; ii < tail_i64 - head_i64; ii++)
    {
        fseek(fpif, dst_offset + sizeof(int64_t) * buf_lst[ii * 2], SEEK_SET);
        fread((void*) &buf_pos, sizeof(int64_t), 1, fpif);

        buf_pos += buf_lst[ii * 2 + 1];

        fseek(fpif, ide_offset + (sizeof(int64_t) + sizeof(float complex)) * buf_pos + sizeof(int64_t), SEEK_SET);
        fread((void*) &buf_c32, sizeof(float complex), 1, fpif);

        printf("%15ld: % .7E + % .7E * i\n", buf_lst[ii * 2], crealf(buf_c32), cimagf(buf_c32));
    }

    free(buf_lst);
}


void print_snd_idx_i64_c64(FILE *fpif, long ioa_offset, long dst_offset, long ide_offset)
{
    int64_t ii;
    int64_t head_i64, tail_i64;

    size_t iao_sz;
    int64_t *buf_lst;
    int64_t buf_pos;
    double complex buf_c64;

    fread((void*) &head_i64, sizeof(int64_t), 1, fpif);
    fread((void*) &tail_i64, sizeof(int32_t), 1, fpif);

    iao_sz = (size_t) (tail_i64 - head_i64);
    buf_lst = (int64_t*) calloc(iao_sz * 2, sizeof(int64_t));

    fseek(fpif, ioa_offset + head_i64 * (sizeof(int64_t) + sizeof(int64_t)), SEEK_SET);
    fread((void*) buf_lst, sizeof(int64_t), iao_sz * 2, fpif);

    for (ii = 0; ii < tail_i64 - head_i64; ii++)
    {
        fseek(fpif, dst_offset + sizeof(int64_t) * buf_lst[ii * 2], SEEK_SET);
        fread((void*) &buf_pos, sizeof(int64_t), 1, fpif);

        buf_pos += buf_lst[ii * 2 + 1];

        fseek(fpif, ide_offset + (sizeof(int64_t) + sizeof(double complex)) * buf_pos + sizeof(int64_t), SEEK_SET);
        fread((void*) &buf_c64, sizeof(double complex), 1, fpif);

        printf("%15ld: % .15lE + % .15lE * i\n", buf_lst[ii * 2], creal(buf_c64), cimag(buf_c64));
    }

    free(buf_lst);
}


void print_snd_idx_i64_i32(FILE *fpif, long ioa_offset, long dst_offset, long ide_offset)
{
    int64_t ii;
    int64_t head_i64, tail_i64;

    size_t iao_sz;
    int64_t *buf_lst;
    int64_t buf_pos;
    int32_t buf_i32;

    fread((void*) &head_i64, sizeof(int64_t), 1, fpif);
    fread((void*) &tail_i64, sizeof(int32_t), 1, fpif);

    iao_sz = (size_t) (tail_i64 - head_i64);
    buf_lst = (int64_t*) calloc(iao_sz * 2, sizeof(int64_t));

    fseek(fpif, ioa_offset + head_i64 * (sizeof(int64_t) + sizeof(int64_t)), SEEK_SET);
    fread((void*) buf_lst, sizeof(int64_t), iao_sz * 2, fpif);

    for (ii = 0; ii < tail_i64 - head_i64; ii++)
    {
        fseek(fpif, dst_offset + sizeof(int64_t) * buf_lst[ii * 2], SEEK_SET);
        fread((void*) &buf_pos, sizeof(int64_t), 1, fpif);

        buf_pos += buf_lst[ii * 2 + 1];

        fseek(fpif, ide_offset + (sizeof(int64_t) + sizeof(int32_t)) * buf_pos + sizeof(int64_t), SEEK_SET);
        fread((void*) &buf_i32, sizeof(int32_t), 1, fpif);

        printf("%15ld: % 7d\n", buf_lst[ii * 2], buf_i32);
    }

    free(buf_lst);
}


void print_snd_idx_i64_i64(FILE *fpif, long ioa_offset, long dst_offset, long ide_offset)
{
    int64_t ii;
    int64_t head_i64, tail_i64;

    size_t iao_sz;
    int64_t *buf_lst;
    int64_t buf_pos;
    int64_t buf_i64;

    fread((void*) &head_i64, sizeof(int64_t), 1, fpif);
    fread((void*) &tail_i64, sizeof(int32_t), 1, fpif);

    iao_sz = (size_t) (tail_i64 - head_i64);
    buf_lst = (int64_t*) calloc(iao_sz * 2, sizeof(int64_t));

    fseek(fpif, ioa_offset + head_i64 * (sizeof(int64_t) + sizeof(int64_t)), SEEK_SET);
    fread((void*) buf_lst, sizeof(int64_t), iao_sz * 2, fpif);

    for (ii = 0; ii < tail_i64 - head_i64; ii++)
    {
        fseek(fpif, dst_offset + sizeof(int64_t) * buf_lst[ii * 2], SEEK_SET);
        fread((void*) &buf_pos, sizeof(int64_t), 1, fpif);

        buf_pos += buf_lst[ii * 2 + 1];

        fseek(fpif, ide_offset + (sizeof(int64_t) + sizeof(int64_t)) * buf_pos + sizeof(int64_t), SEEK_SET);
        fread((void*) &buf_i64, sizeof(int64_t), 1, fpif);

        printf("%15ld: % 15ld\n", buf_lst[ii * 2], buf_i64);
    }

    free(buf_lst);
}
